//
// Created by aruba on 2020/10/21.
//

#include "_ffmpeg_decoder.h"

FFmpegDecoder::FFmpegDecoder() {
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
}

//设置解码器
void FFmpegDecoder::setAvCodecContext(AVCodecContext *codecContext) {
    this->codecContext = codecContext;
}

//从队列中获取一帧数据(消费者)
int FFmpegDecoder::get(AVPacket *packet) {
    //锁住
    pthread_mutex_lock(&mutex);
//    __android_log_print(ANDROID_LOG_ERROR, LOG_TAG_FFMPEG_DECODER,
//                        "锁住");
    while (isPlay) {
        if (!queue.empty()) {//queue不为空,取出packet，队列为空，则等待生成者生产
//            __android_log_print(ANDROID_LOG_ERROR, LOG_TAG_FFMPEG_DECODER,
//                                "queue不为空");
//            __android_log_print(ANDROID_LOG_ERROR, LOG_TAG_FFMPEG_DECODER,
//                                "packet:%p queue.front()：%p", packet, queue.front());
            //从队列取出一个packet   clone一个 给入参对象
            av_packet_unref(packet);//减少之前的引用
            if (av_packet_ref(packet, queue.front())) {
                //clone失败
                break;
            }

//            __android_log_print(ANDROID_LOG_ERROR, LOG_TAG_FFMPEG_DECODER,
//                                "clone成功");

            //clone成功，取出Packet并释放内存
            AVPacket *pkt = queue.front();
            queue.pop();
            av_packet_unref(pkt);//减少引用
            av_free_packet(pkt);
//            __android_log_print(ANDROID_LOG_ERROR, LOG_TAG_FFMPEG_DECODER,
//                                "取出成功");
            break;
        } else {
//            __android_log_print(ANDROID_LOG_ERROR, LOG_TAG_FFMPEG_DECODER,
//                                "等待");
            pthread_cond_wait(&cond, &mutex);

        }
    }

    pthread_mutex_unlock(&mutex);
    return 0;
}

//将一帧数据放入队列(生产者)
int FFmpegDecoder::put(AVPacket *packet) {
    AVPacket *avPacketClone = (AVPacket *) (av_malloc(sizeof(AVPacket)));
    av_init_packet(avPacketClone);

    if (av_packet_ref(avPacketClone, packet)) {
        //克隆失败
        return 0;
    }

//    __android_log_print(ANDROID_LOG_ERROR, LOG_TAG_FFMPEG_DECODER, "压入一帧数据 %d", stream_idx);
    pthread_mutex_lock(&mutex);
    queue.push(avPacketClone);
    //给消费者解锁
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
    return 1;
}

//开启播放线程
void FFmpegDecoder::startPlay(void *play(void *), void *arg) {
    pthread_mutex_lock(&mutex);
    isPlay = true;
    pthread_create(&this->p_playid, NULL, play, arg);
    pthread_mutex_unlock(&mutex);
}

void FFmpegDecoder::stop() {
    pthread_mutex_lock(&mutex);
    isPlay = false;
    //解锁等待条件
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
    //等待线程停止
    pthread_join(p_playid, 0);
}

FFmpegDecoder::~FFmpegDecoder() {
    __android_log_print(ANDROID_LOG_ERROR, LOG_TAG_FFMPEG_DECODER,
                        "析构解码类");
    avcodec_close(codecContext);
    codecContext = NULL;
    for (int i = 0; i < queue.size(); ++i) {
        AVPacket *pkt = queue.front();
        queue.pop();
        //释放内存
        av_packet_unref(pkt);
        av_free_packet(pkt);
    }
    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&mutex);
}